#if !defined(_TGS_XB2_COMMON_MATH_API_VECTOR_F32_INL_)
#define _TGS_XB2_COMMON_MATH_API_VECTOR_F32_INL_
#pragma once
TgINLINE TgVEC_F32_04 M_TgVECTOR<TgFLOAT32,4>( const __vector4 vNative )
{
register TgVEC_F32_04 tvResult;
tvResult.m_mData = vNative;
return (tvResult);
}
TgINLINE TgVEC_F32_04 M_SET4( C_TgFLOAT32 fX, C_TgFLOAT32 fY, C_TgFLOAT32 fZ, C_TgFLOAT32 fW )
{
__vector4 v0 = __vrlimi(__lvlx(&fX, 0), __lvlx(&fY, 0), 0x4, 3);
__vector4 v1 = __vrlimi(__lvlx(&fZ, 0), __lvlx(&fW, 0), 0x4, 3);
return (M_TgVECTOR<TgFLOAT32,4>( __vrlimi( v0, v1, 0x3, 2 ) ));
}
template <TgUINT32 uiPerm> TgVEC_F32_04 M_PERM( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vpermwi( tvLeft.m_mData, uiPerm ) ));
}
TgINLINE TgVEC_F32_04 M_ADD( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vaddfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_MAD( M_TgVEC_F32_04 tvM0, M_TgVEC_F32_04 tvM1, M_TgVEC_F32_04 tvA0 )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmaddfp( tvM0.m_mData, tvM1.m_mData, tvA0.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_NMS( M_TgVEC_F32_04 tvM0, M_TgVEC_F32_04 tvM1, M_TgVEC_F32_04 tvA0 )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vnmsubfp( tvM0.m_mData, tvM1.m_mData, tvA0.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_DOT3( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmsum3fp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_DOT4( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmsum4fp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_MUL( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_DIV( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_SUB( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vsubfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_LSQ( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmsum4fp( tvLeft.m_mData, tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_LEN( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vrefp( __vrsqrtefp( __vmsum4fp( tvLeft.m_mData, tvLeft.m_mData ) ) ) ));
}
TgINLINE TgVEC_F32_04 M_NEG( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vxor( TgVEC04_MASK::mSgnM.m_u32_v04.m_mData, tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_SQRT( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vrefp( __vrsqrtefp( tvLeft.m_mData ) ) ));
}
TgINLINE TgVEC_F32_04 M_RSQRT( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vrsqrtefp( tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_NORM( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( tvLeft.m_mData, __vrsqrtefp( __vmsum4fp( tvLeft.m_mData, tvLeft.m_mData ) ) ) ));
}
TgINLINE TgVEC_F32_04 M_NORM( PCU_TgVEC_F32_04 tvRet_Length, M_TgVEC_F32_04 tvLeft )
{
const register __vector4 vL0 = __vrsqrtefp( __vmsum4fp( tvLeft.m_mData, tvLeft.m_mData ) );
*tvRet_Length = M_TgVECTOR<TgFLOAT32,4>( __vrefp( vL0 ) );
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( tvLeft.m_mData, vL0 ) ));
}
TgINLINE TgVEC_F32_04 M_FLR( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vrfim( tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CEL( M_TgVEC_F32_04 tvLeft )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vrfip( tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CLP( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvMin, M_TgVEC_F32_04 tvMax )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmaxfp( tvMin.m_mData, __vminfp( tvMax.m_mData, tvLeft.m_mData ) ) ));
}
TgINLINE TgVEC_F32_04 M_SAT( M_TgVEC_F32_04 tvLeft )
{
return (M_CLP( tvLeft, TgVEC_F32_04_K::ZERO, TgVEC_F32_04_K::ONE ));
}
TgINLINE TgVEC_F32_04 M_MAX( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vmaxfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_MIN( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vminfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_IsNaN( M_TgVEC_F32_04 tvLeft )
{
return (M_CMP_EQ( M_AND( tvLeft, TgVEC04_MASK::mNaN.m_f32_v04 ), TgVEC04_MASK::mNaN.m_f32_v04 ));
}
TgINLINE TgVEC_F32_04 M_InBND( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvBound )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpequw( __vcmpbfp( tvLeft.m_mData, tvBound.m_mData ), __vspltisw( 0 ) ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_EQ( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpeqfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_NE( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vxor( TgKV_FFFF.m_mData, __vcmpeqfp( tvLeft.m_mData, tvRight.m_mData ) ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_GE( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpgefp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_GT( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpgtfp( tvLeft.m_mData, tvRight.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_LE( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpgefp( tvRight.m_mData, tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CMP_LT( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
return (M_TgVECTOR<TgFLOAT32,4>( __vcmpgtfp( tvRight.m_mData, tvLeft.m_mData ) ));
}
TgINLINE TgVEC_F32_04 M_CX( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
const __vector4 vX1 = __vpermwi( tvLeft.m_mData, 0x63 );
const __vector4 vX2 = __vpermwi( tvRight.m_mData, 0x87 );
const __vector4 vX3 = __vpermwi( tvLeft.m_mData, 0x87 );
const __vector4 vX4 = __vpermwi( tvRight.m_mData, 0x63 );
return (M_TgVECTOR<TgFLOAT32,4>( __vnmsubfp( vX3, vX4, __vmulfp( vX1, vX2 ) ) ));
}
TgINLINE TgVEC_F32_04 M_UCX( M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
const __vector4 vX1 = __vpermwi( tvLeft.m_mData, 0x63 );
const __vector4 vX2 = __vpermwi( tvRight.m_mData, 0x87 );
const __vector4 vX3 = __vpermwi( tvLeft.m_mData, 0x87 );
const __vector4 vX4 = __vpermwi( tvRight.m_mData, 0x63 );
const __vector4 vF0 = __vnmsubfp( vX3, vX4, __vmulfp( vX1, vX2 ) );
const __vector4 vT0 = __vmsum4fp( vF0, vF0 );
const __vector4 vL0 = __vrsqrtefp( vT0 );
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( vF0, vL0 ) ));
}
TgINLINE TgVEC_F32_04 M_UCX( PCU_TgVEC_F32_04 tvRet_Length, M_TgVEC_F32_04 tvLeft, M_TgVEC_F32_04 tvRight )
{
const __vector4 vX1 = __vpermwi( tvLeft.m_mData, 0x63 );
const __vector4 vX2 = __vpermwi( tvRight.m_mData, 0x87 );
const __vector4 vX3 = __vpermwi( tvLeft.m_mData, 0x87 );
const __vector4 vX4 = __vpermwi( tvRight.m_mData, 0x63 );
const __vector4 vF0 = __vnmsubfp( vX3, vX4, __vmulfp( vX1, vX2 ) );
const __vector4 vT0 = __vmsum4fp( vF0, vF0 );
const __vector4 vL0 = __vrsqrtefp( vT0 );
*tvRet_Length = M_TgVECTOR<TgFLOAT32,4>( __vrefp( vL0 ) );
return (M_TgVECTOR<TgFLOAT32,4>( __vmulfp( vF0, vL0 ) ));
}
TgINLINE TgVEC_F32_04 M_SETP( C_TgFLOAT32 fX, C_TgFLOAT32 fY, C_TgFLOAT32 fZ )
{
return (M_SET4( fX, fY, fZ, 1.0F ));
}
TgINLINE TgVEC_F32_04 M_SETV( C_TgFLOAT32 fX, C_TgFLOAT32 fY, C_TgFLOAT32 fZ )
{
return (M_SET4( fX, fY, fZ, 0.0F ));
}
TgINLINE TgVEC_F32_04 M_SETP( M_TgVEC_F32_04 tvRight )
{
return (M_OR( TgVEC_F32_04_K::UNIT_W, M_AND( tvRight, TgVEC04_MASK::mFFF0.m_f32_v04 ) ));
}
TgINLINE TgVEC_F32_04 M_SETV( M_TgVEC_F32_04 tvRight )
{
return (M_AND( tvRight, TgVEC04_MASK::mFFF0.m_f32_v04 ));
}
#endif